package Offer.offer2019;

/**
 * 数值的整数次方
 * @author: leiwenkang02@meituan.com
 * @date: 2019/4/24
 * @time: 19:23
 */
public class Offer11 {
    /**
     * 常规思路，不够高效
     * 注意代码的健壮性
     */
    public double Power(double base, int exponent) {
        //0的负数次方，应该特殊处理，否则会出现算数异常
        if (isEqual(base, 0) && exponent < 0) {
            throw new RuntimeException("非法输入");
        }

        if (exponent < 0) {
            exponent = -exponent;
        }

        double result = 1.0;
        for (int i = 0; i < exponent; i++) {
            result *= base;
        }
        if (exponent < 0) {
            result = 1.0 / result;
        }
        return result;
    }

    /**
     * double比较，不要直接写==0，实际情况我们会转化为BigDecimal比较
     */
    private boolean isEqual(double base1, double base2) {
        if (base1 - base2 > -0.000000001 && base1 - base2 < 0.000000001) {
            return true;
        }
        return false;
    }


    /**
     * 高效思路  递归
     * 比如我们要求2的8次方，可以先求得2的4次方，要求2的4次方，我们求到2的2次方就行了
     */
    public double Power2(double base, int exponent) {
        //0的负数次方，应该特殊处理，否则会出现算数异常
        if (isEqual(base, 0) && exponent < 0) {
            throw new RuntimeException("非法输入");
        }
        if (exponent == 0) {
            return 1;
        }

        if (exponent == 1) {
            return base;
        }

        double result = Power2(base, exponent >> 1);
        result *= result;

        if ((exponent & 1) == 1) {
            result *= base;
        }
        return result;
    }
}
